/*
 * Copyright (c) 2017, apexes.net. All rights reserved.
 *
 *         http://www.apexes.net
 *
 */
package net.apexes.wsonrpc.core;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author <a href=mailto:hedyn@foxmail.com>HeDYn</a>
 */
class ServiceReflectHolder<T> {

    private final Map<String, ServiceMethodInvoker> invokerFinder = new ConcurrentHashMap<>();

    ServiceReflectHolder(Class<T> interfaceClass, T instance) {
        if (interfaceClass == null) {
            throw new NullPointerException("interfaceClass");
        }
        if (instance == null) {
            throw new NullPointerException("instance");
        }
        if (!interfaceClass.isInterface()) {
            throw new IllegalArgumentException("class should be an interface : " + interfaceClass);
        }
        if (!interfaceClass.isInstance(instance)) {
            throw new IllegalArgumentException("instance should be implements " + interfaceClass);
        }

        Map<String, Set<Method>> map = new HashMap<>();
        for (Method method : interfaceClass.getMethods()) {
            String methodName = method.getName();
            Set<Method> set = map.computeIfAbsent(methodName, k -> new HashSet<>());
            set.add(method);
        }
        for (Map.Entry<String, Set<Method>> entry : map.entrySet()) {
            String methodName = entry.getKey();
            Set<Method> methods = entry.getValue();
            ServiceMethodInvoker invoker = new ServiceMethodInvoker(instance, methods);
            invokerFinder.put(methodName, invoker);
        }
    }

    ServiceMethodInvoker findInvoker(String methodName) {
        return invokerFinder.get(methodName);
    }

}
